package algorithm.markovLink;

import static algorithm.markovLink.Utils.char2Idx;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 从文件中读取单词, 统计字母链接概率
 * 
 * 
 * 
 * @author chenwei
 * 
 */
public class ReadCorpus {

	private static final int ROWS = 26 + 2;// 0 ~ 27
	private static final int COLS = ROWS;
	private int[][] matrix = new int[ROWS][COLS];
	private Pattern pattern = Pattern.compile("[a-zA-Z]{3,}");

	public int[][] read_corpus(String... corpusPaths) throws IOException {
		for (String path : corpusPaths)
			read_corpus(path);

		// initial last column;
		int rowSum;
		for (int i = 0; i < matrix.length; i++) {
			rowSum = 0;
			for (int j = 0; j < matrix[i].length; j++)
				rowSum += matrix[i][j];
			matrix[i][COLS - 1] = rowSum;
		}
		return matrix;
	}

	private void read_corpus(File corpusFile) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(corpusFile), "utf-8"));

		String line;
		char preChar = 0;
		char currChar = 0;
		while ((line = reader.readLine()) != null) {
			for (String word : parseWords(line)) {
				for (int i = 0; i < word.length(); i++) {
					currChar = word.charAt(i);// get current character
					if (i == 0) {
						// if currChar is first char in the word
						// last row increase
						matrix[ROWS - 1][char2Idx(currChar)]++;
					} else {
						matrix[char2Idx(preChar)][char2Idx(currChar)]++;
					}
					if (i == word.length() - 1) {
						// if currChar is last char in the word
						// last-1 column increase
						matrix[char2Idx(currChar)][COLS - 2]++;
					}
					preChar = currChar;
				}
			}
		}
		reader.close();
	}

	private List<String> parseWords(String line) {
		List<String> words = new ArrayList<String>(30);
		Matcher m = pattern.matcher(line);
		while (m.find())
			words.add(m.group().toLowerCase());
		return words;
	}

	private void read_corpus(String corpusPath) throws IOException {
		read_corpus(new File(corpusPath));
	}
}
